home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Graphics / sKulpt / skulpt-src / D3d-Misc.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-07-18  |  9.5 KB  |  313 lines

  1. #define STRICT
  2.  
  3. // Includes standard Windows
  4. #include <windows.h>
  5. #include <windowsx.h>
  6. #include <time.h>
  7. #include <stdlib.h>
  8. #include <malloc.h>
  9. #include <memory.h>
  10. #include <stdio.h>
  11.  
  12. // Includes D3D
  13. #define  D3D_OVERLOADS
  14. #include <ddraw.h>
  15. #include <d3d.h>
  16. #include <d3dx.h>
  17.  
  18. // Includes utilitaires D3D
  19. #include "d3dmath.h"
  20. #include "d3dutil.h"
  21. #include "D3DEnum.h"
  22.  
  23. // Ids Resources
  24. #include "resource.h"
  25.  
  26. // Constantes
  27. #include "const.h"
  28.  
  29. // Types
  30. #include "types.h"
  31.  
  32. // Variables globales projet
  33. #include "vars.h"
  34.  
  35. // Prototypes fonctions autres modules
  36. #include "proto.h"
  37.  
  38. // Macros
  39. #include "macros.h"
  40.  
  41. //-----------------------------------------------------------------------------
  42. // Name: EnumZBufferCallback()
  43. // Desc: Enumeration function to report valid pixel formats for z-buffers.
  44. //-----------------------------------------------------------------------------
  45. static HRESULT WINAPI hrEnumZBufferCallback( DDPIXELFORMAT* pddpf,
  46.                                            VOID* pddpfDesired )
  47. {
  48. #ifndef NO3D
  49.     // For this tutorial, we are only interested in z-buffers, so ignore any
  50.     // other formats (e.g. DDPF_STENCILBUFFER) that get enumerated. An app
  51.     // could also check the depth of the z-buffer (16-bit, etc,) and make a
  52.     // choice based on that, as well. For this tutorial, we'll take the first
  53.     // one we get.
  54.     if( pddpf->dwFlags == DDPF_ZBUFFER )
  55.     {
  56.         memcpy( pddpfDesired, pddpf, sizeof(DDPIXELFORMAT) );
  57.         vTrace("ZBuffer depth : %d bit", ((DDPIXELFORMAT *) pddpfDesired) -> dwZBufferBitDepth);
  58.  
  59.         // Return with D3DENUMRET_CANCEL to end the search.
  60.         return D3DENUMRET_CANCEL;
  61.     }
  62. #endif
  63.     // Return with D3DENUMRET_OK to continue the search.
  64.     return D3DENUMRET_OK;
  65. }
  66.  
  67. ////////////////////////////////////////////////////////////////////////////
  68. HRESULT hrPreInitD3D(void)
  69. {
  70.     HRESULT hr = S_OK;
  71.  
  72. #ifndef NO3D
  73.     // Create DirectDraw interface.
  74.     vTrace("Création interface DirectDraw7");
  75.     hr = DirectDrawCreateEx (NULL, (void **)&lpDD, IID_IDirectDraw7, NULL); 
  76.     if( FAILED( hr ) )
  77.         return hr;
  78.  
  79.     // Get an IDirect3D7 interface
  80.     vTrace("Définition interface Direct3D V7");
  81.     hr = lpDD->QueryInterface (IID_IDirect3D7, (void **)&lpD3D);
  82. #endif
  83.  
  84.     return hr;
  85. }
  86.  
  87. ////////////////////////////////////////////////////////////////////////////
  88. HRESULT hrInitD3D(HWND hWnd, const GUID* pDeviceGUID)
  89. {
  90.     HRESULT hr = S_OK;
  91. #ifndef NO3D
  92.  
  93.     // Set the Windows cooperative level. The flag DDSCL_NORMAL specifies windowed mode.
  94.     vTrace("Demande mode fenêtré (mode coopératif)");
  95.     hr = lpDD->SetCooperativeLevel( hWnd, DDSCL_NORMAL );
  96.     if( FAILED( hr ) )
  97.         return hr;
  98.  
  99.     // Initialize a surface description structure for the Render surface.
  100.     vTrace("Initialisation du descripteur de surface Render");
  101.     ZeroMemory( &ddsd, sizeof(DDSURFACEDESC2) );
  102.     ddsd.dwSize         = sizeof(DDSURFACEDESC2);
  103.     ddsd.dwFlags        = DDSD_CAPS;
  104.     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  105.  
  106.     // Create the Render surface.
  107.     vTrace("Création de la surface Render");
  108.     hr = lpDD->CreateSurface( &ddsd, &lpddsRender, NULL );
  109.     if( FAILED( hr ) )        return hr;
  110.  
  111.     // Setup a surface description to create a backbuffer with dimensions equal to our window size.
  112.     vTrace("Initialisation du descripteur de surface BackBuffer");
  113.     ddsd.dwFlags        = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
  114.     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
  115.  
  116.     // Set the dimensions of the backbuffer. Note that if our window changes
  117.     // size, we need to destroy this surface and create a new one.
  118.     vTrace("Dimensionnement de la surface BackBuffer");
  119.     GetClientRect( hWnd, &sRectangle );
  120.     ClientToScreen( hWnd, (POINT*)&sRectangle.left );
  121.     ClientToScreen( hWnd, (POINT*)&sRectangle.right );
  122.     ddsd.dwWidth  = sRectangle.right - sRectangle.left;
  123.     ddsd.dwHeight = sRectangle.bottom - sRectangle.top;
  124.  
  125.     // Create the backbuffer.
  126.     vTrace("Création de la la surface BackBuffer");
  127.     hr = lpDD->CreateSurface( &ddsd, &lpddsBackBuffer, NULL );
  128.     if( FAILED( hr ) )
  129.         return hr;
  130.  
  131.     // Create a clipper object which handles all our clipping for cases when
  132.     // our window is partially obscured by other windows.
  133.     vTrace("Création du clipper");
  134.     LPDIRECTDRAWCLIPPER pcClipper;
  135.     hr = lpDD->CreateClipper( 0, &pcClipper, NULL );
  136.     if( FAILED( hr ) )
  137.         return hr;
  138.  
  139.     // Associate the clipper with our window.
  140.     vTrace("Association clipper <-> fenêtre");
  141.     pcClipper->SetHWnd( 0, hWnd );
  142.     lpddsRender->SetClipper( pcClipper );
  143.     pcClipper->Release();
  144.     
  145.     // Create the z-buffer AFTER creating the backbuffer and BEFORE creating the d3ddevice.
  146.     DDPIXELFORMAT ddpfZBuffer;
  147.     lpD3D->EnumZBufferFormats( *pDeviceGUID, 
  148.                                 hrEnumZBufferCallback, (VOID*)&ddpfZBuffer );
  149.  
  150.     // If we found a good zbuffer format, then the dwSize field will be
  151.     // properly set during enumeration. Else, we have a problem and will exit.
  152.     if( sizeof(DDPIXELFORMAT) != ddpfZBuffer.dwSize )
  153.         return E_FAIL;
  154.  
  155.     // Get z-buffer dimensions from the render target
  156.     // Setup the surface desc for the z-buffer.
  157.     ddsd.dwFlags        = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
  158.     ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
  159.     ddsd.dwWidth        = sRectangle.right - sRectangle.left;
  160.     ddsd.dwHeight       = sRectangle.bottom - sRectangle.top;
  161.     memcpy( &ddsd.ddpfPixelFormat, &ddpfZBuffer, sizeof(DDPIXELFORMAT) );
  162.  
  163.     // For hardware devices, the z-buffer should be in video memory. For
  164.     // software devices, create the z-buffer in system memory
  165.     if( IsEqualIID( *pDeviceGUID, IID_IDirect3DHALDevice )  ||
  166.         IsEqualIID( *pDeviceGUID, IID_IDirect3DTnLHalDevice ) )
  167.         ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
  168.     else
  169.         ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
  170.  
  171.     // Create and attach a z-buffer. Real apps should be able to handle an
  172.     // error here (DDERR_OUTOFVIDEOMEMORY may be encountered). For this 
  173.     // tutorial, though, we are simply going to exit ungracefully.
  174.     if( FAILED( hr = lpDD->CreateSurface( &ddsd, &g_pddsZBuffer, NULL ) ) )
  175.         return hr;
  176.  
  177.     // Attach the z-buffer to the back buffer.
  178.     if( FAILED( hr = lpddsBackBuffer->AddAttachedSurface( g_pddsZBuffer ) ) )
  179.         return hr;
  180.  
  181.     // Check that we are NOT in a palettized display.
  182.     vTrace("Vérification true color");
  183.     ddsd.dwSize = sizeof(DDSURFACEDESC2);
  184.     lpDD->GetDisplayMode( &ddsd );
  185.     if( ddsd.ddpfPixelFormat.dwRGBBitCount <= 8 )
  186.         return DDERR_INVALIDMODE;
  187.  
  188.     // Create the device (hardware renderer).
  189.     vTrace("Création device 3D");
  190.     hr = lpD3D->CreateDevice( *pDeviceGUID, lpddsBackBuffer,
  191.                                &lpd3dDevice );
  192.     if( FAILED( hr ) )
  193.     {
  194.         vTrace("*** E0007 : Echec création device 3D.");
  195.         return hr;
  196.     }
  197.     else
  198.         vTrace("Succès création device 3D.");
  199.  
  200.     // Store device ID (to reuse later when resizing the window)
  201.     gDeviceGUID = *pDeviceGUID;
  202.  
  203.     // Create the viewport
  204.     vTrace("Création viewport");
  205.     DWORD dwRenderWidth  = sRectangle.right - sRectangle.left;
  206.     DWORD dwRenderHeight = sRectangle.bottom - sRectangle.top;
  207.     D3DVIEWPORT7 vp = { 0, 0, dwRenderWidth, dwRenderHeight, 0.0f, 1.0f };
  208.     hr = lpd3dDevice->SetViewport( &vp );
  209.     if( FAILED( hr ) )
  210.         return hr;
  211.  
  212.     vTrace("Initialisation D3D ok.");
  213. #endif
  214.     return hr;
  215. }
  216.  
  217. HRESULT hrCloseD3D(BOOL bFull)
  218. {
  219. #ifndef NO3D
  220.  
  221.     // Release the DDraw and D3D objects used by the app
  222.     if( g_pddsZBuffer )        g_pddsZBuffer->Release();
  223.     if( lpddsBackBuffer )    lpddsBackBuffer->Release();
  224.     if( lpddsRender )        lpddsRender->Release();
  225.  
  226.     // Do a safe check for releasing the D3DDEVICE. RefCount should be zero.
  227.     if( lpd3dDevice )
  228.         if( 0 < lpd3dDevice->Release() )
  229.             return E_FAIL;
  230.  
  231.     g_pddsZBuffer   = NULL;
  232.     lpddsBackBuffer = NULL;
  233.     lpddsRender     = NULL;
  234.     lpd3dDevice     = NULL;
  235.  
  236.     if (bFull)
  237.     {
  238.         D3DXUninitialize();
  239.         if( lpD3D )
  240.             lpD3D->Release();
  241.  
  242.         // Do a safe check for releasing DDRAW. RefCount should be zero.
  243.         if( lpDD )
  244.             if( 0 < lpDD->Release() )
  245.                 return E_FAIL;
  246.  
  247.         lpD3D           = NULL;
  248.         lpDD            = NULL;
  249.     }
  250.  
  251. #endif
  252.  
  253.     return 0;
  254. }
  255.  
  256. // Show the frame on the Render surface
  257. HRESULT hrShowFrame(void)
  258. {
  259. #ifndef NO3D
  260.     if( NULL == lpddsRender )
  261.         return E_FAIL;
  262.  
  263.     // Perform a blit from the backbuffer to the correct position on the Render surface
  264.     return lpddsRender->Blt( &sRectangle, lpddsBackBuffer, 
  265.                                NULL, DDBLT_WAIT, NULL );
  266. #else
  267.     return S_OK;
  268. #endif
  269. }
  270.  
  271. // Checks for lost surfaces and restores them if lost.
  272. HRESULT hrRestoreSurfaces(void)
  273. {
  274. #ifndef NO3D
  275.     // Check/restore the Render surface
  276.     if( lpddsRender )
  277.         if( lpddsRender->IsLost() )
  278.             lpddsRender->Restore();
  279.     
  280.     // Check/restore the back buffer
  281.     if( lpddsBackBuffer )
  282.         if( lpddsBackBuffer->IsLost() )
  283.             lpddsBackBuffer->Restore();
  284. #endif
  285.     return S_OK;
  286. }
  287.  
  288. // Moves the screen rect for windowed renderers
  289. void vOnMove(int x, int y)
  290. {
  291.     DWORD dwWidth  = sRectangle.right - sRectangle.left;
  292.     DWORD dwHeight = sRectangle.bottom - sRectangle.top;
  293.     SetRect( &sRectangle, x, y, x + dwWidth, y + dwHeight );
  294. }
  295.  
  296. // Draws the scene. There are three steps here:
  297. //       (1) Animate the scene
  298. //       (2) Render the scene
  299. //       (3) Show the frame (copy backbuffer contents to the Render).
  300. HRESULT hrRender3DEnvironment(void)
  301. {
  302. #ifndef NO3D
  303.     // Call the app specific function to render the scene
  304.     hrRender( lpd3dDevice );
  305.     
  306.     // Show the frame on the Render surface.
  307.     if( DDERR_SURFACELOST == hrShowFrame() )
  308.         hrRestoreSurfaces();
  309. #endif
  310.     return S_OK;
  311. }
  312.  
  313.